package com.kamistoat.meimeistore.order.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.kamistoat.common.To.EsTo.OrderListTo;
import com.kamistoat.common.To.RabbitMQTo.OrderTo;
import com.kamistoat.common.To.RabbitMQTo.SecKillOrderTo;
import com.kamistoat.common.utils.PageUtils;
import com.kamistoat.common.utils.R;
import com.kamistoat.meimeistore.order.To.OrderCreateTo;
import com.kamistoat.meimeistore.order.entity.OrderEntity;
import com.kamistoat.meimeistore.order.vo.*;
import com.kamistoat.meimeistore.order.vo.*;

import java.util.Map;

/**
 * 订单
 *
 * @author kamistoat
 * @email linjianshanke@163.com
 * @date 2021-09-12 16:42:29
 */
public interface OrderService extends IService<OrderEntity> {

    PageUtils queryPage(Map<String, Object> params);

    /**
     * 当用户点击购物车结算时，查出订单检查页面所需要的所有数据
     * @return
     */
    OrderCheckVo checkOrder();

    /**
     * 如果一个商品正在参与秒杀，则当点击抢购时，仅仅验证信号量锁是否放行。
     * 通过后调用此URL，跳转到订单确认页，此时已不是直面全部流量了。则可以对秒杀数据进行全面校验。
     * 专门给秒杀商品用的，和上面的普通toTrade区分
     * @return
     */
    R checkSeckillOrder(Long sessionProId, String randomCode, Long skuId, Integer wantNum);

    /**
     * 结算页下单进入支付页
     * @param orderSubmitVo
     * @return
     */
    SubmitOrderResponseVo submitOrder(OrderSubmitVo orderSubmitVo);

    /**
     * 秒杀订单提价订单。
     * @return 等待支付页。但是注意，秒杀高并发下，只能保证缓存中一定存在订单，数据库中订单是否入库未知
     */
    R submitSeckillOrder(OrderSubmitVo orderSubmitVo);

    /**
     * 关闭订单
     */
    void closeOrder(OrderTo orderTo);

    /**
     * 根据orderSN制作支付vo
     * @param orderSn
     * @return
     */
    PayVo getOrderPay(String orderSn);

    /**
     * 查询当前用户的所有订单，支付成功后同样跳转到这个页面
     * @param params
     * @return
     */
    PageUtils queryPageByUser(Map<String, Object> params);

    /**
     * 接收支付宝的异步消息
     * @param payAsyncVo
     * @return
     */
    String handlePayedNotify(PayAsyncVo payAsyncVo);

    /**
     * 创建秒杀订单
     * @param secKillOrderTo 消息队列中的秒杀信息
     */
    void secKillOrder(SecKillOrderTo secKillOrderTo);

    /**
     * 新秒杀逻辑下，监听到消息队列中的 未支付状态的新秒杀订单，将其入库
     * @param orderCreateTo 未支付状态的秒杀订单
     */
    void saveSeckillNewOrder(OrderCreateTo orderCreateTo);

    /**
     * 确认收货。不管是手动确认还是自动确认都调用此方法
     * @param orderSN
     * @return
     */
    R confirmOrder(String orderSN);

    /**
     * 当未支付的总订单入库时，Canal监听到通知这里，由这个方法构建 OrderListTo
     * @param topOrderId
     * @param topOrderSn
     * @return
     */
    OrderListTo getNewOrderAsync(Long topOrderId, String topOrderSn);

    /**
     * 当有一个总订单完成支付时，Canal监听到数据库的更改来到这里，由这个方法构建OrderListTo
     * @param topOrderId
     * @param topOrderSn
     * @return
     */
    OrderListTo getUpdateOrderAsync(Long topOrderId, String topOrderSn);
}

